namespace OpenComposite.EII.Repository
{
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Drawing;
	using System.Messaging;
	using System.Text;
	using System.Windows.Forms;
	using System.Xml;

	using OpenComposite.EII.RepositoryUIs;

	using OpenComposite.Base.Collections;
	using OpenComposite.Mapper;
	using OpenComposite.Repository.Properties;

	[RepositoryItem(ItemType.LogicalWebMethod, "logical_webmethods", "log_wmeth_id")]
	public class LogicalWebMethod : RepositoryItemBaseEx, ISupportLogicalPhysicalMapping
	{
		#region Initialization

		/// <summary>
		/// Initializes a new instance of the <see cref="LogicalWebMethod"/> class.
		/// </summary>
		/// <param name="serviceProvider">The service provider.</param>
		/// <param name="bCreateNew">if set to <c>true</c> [b create new].</param>
		public LogicalWebMethod(IServiceProvider serviceProvider, bool bCreateNew)
			: base("log_wmeth_id", "log_wmeth_nm", "log_wmeth_desc", "log_wmeth_ntext", Resources.sNewLogicalWebMethod)
		{
			if ( bCreateNew )
				this.CreateNew();

			InitializeServiceProvider(serviceProvider);
		}

		#endregion Initialization

		#region Public Members

		#region Properties

		/// <summary>
		/// Gets the allowed child types.
		/// </summary>
		/// <value>The allowed child types.</value>
		public override List<ItemType> AllowedChildTypes
		{
			get { return null; }
		}

		/// <summary>
		/// Gets or sets the callback web method.
		/// </summary>
		/// <value>The callback web method.</value>
		public WebMethod CallbackWebMethod
		{
			get { return RepositoryService.GetItem<WebMethod>(CallbackWebMethodID); }
			set
			{
				if ( value == null ) CallbackWebMethodID = -1;
				else CallbackWebMethodID = value.ID;
			}
		}

		/// <summary>
		/// Gets or sets the callback web method ID.
		/// </summary>
		/// <value>The callback web method ID.</value>
		public int CallbackWebMethodID
		{
			get { return getInt("callback_webmethod_id", -1); }
			set { setValue("CallbackWebMethodID", "callback_webmethod_id", value); }
		}

		/// <summary>
		/// Gets or sets the endpoint rule.
		/// </summary>
		/// <value>The endpoint rule.</value>
		public RepositoryBusinessRule EndpointRule
		{
			get { return RepositoryService.GetItem<RepositoryBusinessRule>(EndpointRuleID); }
			set
			{
				if ( value == null ) EndpointRuleID = -1;
				else EndpointRuleID = value.ID;
			}
		}

		/// <summary>
		/// Gets or sets the endpoint rule ID.
		/// </summary>
		/// <value>The endpoint rule ID.</value>
		public int EndpointRuleID
		{
			get { return getInt("endpoint_brule_id", -1); }
			set { setValue("EndpointRuleID", "endpoint_brule_id", value); }
		}

		/// <summary>
		/// Gets the extended properties.
		/// </summary>
		/// <value>The extended properties.</value>
		public LogicalMethodProperties ExtendedProperties
		{
			get
			{
				if ( _properties == null ) {
					_properties = getXmlSerializedObject<LogicalMethodProperties>("diagram");
					if ( _properties == null )
						_properties = new LogicalMethodProperties();
				}
				return _properties;
			}
		}

		/// <summary>
		/// Gets or sets the human activity.
		/// </summary>
		/// <value>The human activity.</value>
		public HumanActivity HumanActivity
		{
			get { return RepositoryService.GetItem<HumanActivity>(HumanActivityID); }
			set { HumanActivityID = value == null ? -1 : value.ID; }
		}

		/// <summary>
		/// Gets or sets the human activity ID.
		/// </summary>
		/// <value>The human activity ID.</value>
		public int HumanActivityID
		{
			get { return getInt("hact_id", -1); }
			set { setValue("HumanActivityID", "hact_id", value); }
		}

		/// <summary>
		/// Gets the image.
		/// </summary>
		/// <value>The image.</value>
		public override System.Drawing.Image Image
		{
			get { return Resources.png_logical_method; }
		}

		/// <summary>
		/// Gets the image key.
		/// </summary>
		/// <value>The image key.</value>
		public override string ImageKey
		{
			get { return "logical_method"; }
		}

		/// <summary>
		/// Gets or sets the input business object.
		/// </summary>
		/// <value>The input business object.</value>
		public BusinessObject InputBusinessObject
		{
			get
			{
				if ( this.InputBusinessObjectID > 0 ) {
					return this.RepositoryService.GetItem<BusinessObject>(this.InputBusinessObjectID);
				} else {
					return null;
				}
			}
			set { this.InputBusinessObjectID = ( value == null ? -1 : value.ID ); }
		}

		/// <summary>
		/// Gets or sets the input business object ID.
		/// </summary>
		/// <value>The input business object ID.</value>
		public int InputBusinessObjectID
		{
			get { return getInt("input_bobj_id", -1); }
			set
			{
				if ( this.InputBusinessObjectID == value ) return; // EXIT
				BindingListEx<Verb> lst = Global.Data.GetVerbsOfLogicalMethod(this.ID);
				if ( lst.Count > 0 ) {
					DialogResult result = MessageBox.Show(
						string.Format("This will change the Input Business Object of all assigned capabilities.{0}{0}Do you really want to continue?", Environment.NewLine),
						"Change Input Business Object", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
					if ( result == DialogResult.No ) return; // EXIT
					setValue("InputBusinessObjectID", "input_bobj_id", value);
					foreach ( var item in lst ) {
						item.SetInputBusinessObjectID(value);
						item.Save();
					}
					return; // EXIT
				}
				setValue("InputBusinessObjectID", "input_bobj_id", value);
			}
		}

		/// <summary>
		/// Gets or sets the input code mapping.
		/// </summary>
		/// <value>The input code mapping.</value>
		public string InputCodeMapping
		{
			get { return ExtendedProperties.InputCodeMapping; }
			set { ExtendedProperties.InputCodeMapping = value; }
		}

		/// <summary>
		/// Gets or sets the input connections.
		/// </summary>
		/// <value>The input connections.</value>
		public string InputConnections
		{
			get { return getString("input_connections", null); }
			set { setValue("InputConnections", "input_connections", value); }
		}

		/// <summary>
		/// Gets or sets the input XSLT.
		/// </summary>
		/// <value>The input XSLT.</value>
		public XsltDocument InputXSLT
		{
			get
			{
				string sXslt = getString("input_xslt", null);
				XsltDocument xslt = null;
				if ( !string.IsNullOrEmpty(sXslt) ) {
					xslt = new XsltDocument();
					xslt.LoadXml(sXslt);
				}
				return xslt;
			}
			set { setXmlDocument("InputXSLT", "input_xslt", value); }
		}

		/// <summary>
		/// Gets the is assigned to.
		/// </summary>
		/// <value>The is assigned to.</value>
		public LogicalMethodAssignedTo IsAssignedTo
		{
			get
			{
				if ( this.EndpointRuleID > 0 ) {
					return LogicalMethodAssignedTo.EndpointRule;
				} else if ( this.HumanActivityID > 0 ) {
					return LogicalMethodAssignedTo.HumanActivity;
				} else if ( this.SendMessageQueueID > 0 ||
							this.ReceiveMessageQueueID > 0 ) {
					return LogicalMethodAssignedTo.MessageQueue;
				} else {
					return LogicalMethodAssignedTo.WebServiceMethod;
				}
			}
		}

		/// <summary>
		/// Gets a value indicating whether this instance is MSMQ async.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this instance is MSMQ async; otherwise, <c>false</c>.
		/// </value>
		public bool IsMsmqAsync
		{
			get { return !( ReceiveMessageQueue != null && SendMessageQueue != null ); }
		}

		/// <summary>
		/// Gets or sets the output business object.
		/// </summary>
		/// <value>The output business object.</value>
		public BusinessObject OutputBusinessObject
		{
			get
			{
				if ( this.OutputBusinessObjectID > 0 ) {
					return this.RepositoryService.GetItem<BusinessObject>(this.OutputBusinessObjectID);
				} else {
					return null;
				}
			}
			set { this.OutputBusinessObjectID = ( value == null ? -1 : value.ID ); }
		}

		/// <summary>
		/// Gets or sets the output business object ID.
		/// </summary>
		/// <value>The output business object ID.</value>
		public int OutputBusinessObjectID
		{
			get { return getInt("output_bobj_id", -1); }
			set
			{
				if ( this.OutputBusinessObjectID == value ) return; // EXIT
				BindingListEx<Verb> lst = Global.Data.GetVerbsOfLogicalMethod(this.ID);
				if ( lst.Count > 0 ) {
					DialogResult result = MessageBox.Show(
						string.Format("This will change the Output Business Object of all assigned capabilities.{0}{0}Do you really want to continue?", Environment.NewLine),
						"Change Output Business Object", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
					if ( result == DialogResult.No ) return; // EXIT
					setValue("OutputBusinessObjectID", "output_bobj_id", value);
					foreach ( var item in lst ) {
						item.SetOutputBusinessObjectID(value);
						item.Save();
					}
					return; // EXIT
				}
				setValue("OutputBusinessObjectID", "output_bobj_id", value);
			}
		}

		/// <summary>
		/// Gets or sets the output code mapping.
		/// </summary>
		/// <value>The output code mapping.</value>
		public string OutputCodeMapping
		{
			get { return ExtendedProperties.OutputCodeMapping; }
			set { ExtendedProperties.OutputCodeMapping = value; }
		}

		/// <summary>
		/// Gets or sets the output connections.
		/// </summary>
		/// <value>The output connections.</value>
		public string OutputConnections
		{
			get { return getString("output_connections", null); }
			set { setValue("OutputConnections", "output_connections", value); }
		}

		/// <summary>
		/// Gets or sets the output XSLT.
		/// </summary>
		/// <value>The output XSLT.</value>
		public XsltDocument OutputXSLT
		{
			get
			{
				string sXslt = getString("output_xslt", null);
				XsltDocument xslt = null;
				if ( !string.IsNullOrEmpty(sXslt) ) {
					xslt = new XsltDocument();
					xslt.LoadXml(sXslt);
				}
				return xslt;
			}
			set { setXmlDocument("OutputXSLT", "output_xslt", value); }
		}

		/// <summary>
		/// Gets the proxy callback web method.
		/// </summary>
		/// <value>The proxy callback web method.</value>
		public WebMethod ProxyCallbackWebMethod
		{
			get
			{
				WebMethod wm = RepositoryService.GetItem<WebMethod>(this.ProxyCallbackWebMethodID);
				if ( wm == null && this.ProxyCallbackWebMethodID > 0 ) this.ProxyCallbackWebMethodID = -1;
				return wm;
			}
		}

		/// <summary>
		/// Gets or sets the proxy callback web method ID.
		/// </summary>
		/// <value>The proxy callback web method ID.</value>
		public int ProxyCallbackWebMethodID
		{
			get { return getInt("proxy_callback_wmeth_id", -1); }
			set { setValue("ProxyCallbackWebMethodID", "proxy_callback_wmeth_id", value); }
		}

		/// <summary>
		/// Gets or sets the proxy input connections.
		/// </summary>
		/// <value>The proxy input connections.</value>
		public string ProxyInputConnections
		{
			get { return getString("proxy_input_connections", null); }
			set { setValue("ProxyInputConnections", "proxy_input_connections", value); }
		}

		/// <summary>
		/// Gets or sets the proxy input XSLT.
		/// </summary>
		/// <value>The proxy input XSLT.</value>
		public XsltDocument ProxyInputXSLT
		{
			get
			{
				string sXslt = getString("proxy_input_xslt", null);
				XsltDocument xslt = null;
				if ( !string.IsNullOrEmpty(sXslt) ) {
					xslt = new XsltDocument();
					xslt.LoadXml(sXslt);
				}
				return xslt;
			}
			set { setXmlDocument("ProxyInputXSLT", "proxy_input_xslt", value); }
		}

		/// <summary>
		/// Gets or sets the proxy output connections.
		/// </summary>
		/// <value>The proxy output connections.</value>
		public string ProxyOutputConnections
		{
			get { return getString("proxy_output_connections", null); }
			set { setValue("ProxyOutputConnections", "proxy_output_connections", value); }
		}

		/// <summary>
		/// Gets or sets the proxy output XSLT.
		/// </summary>
		/// <value>The proxy output XSLT.</value>
		public XsltDocument ProxyOutputXSLT
		{
			get
			{
				string sXslt = getString("proxy_output_xslt", null);
				XsltDocument xslt = null;
				if ( !string.IsNullOrEmpty(sXslt) ) {
					xslt = new XsltDocument();
					xslt.LoadXml(sXslt);
				}
				return xslt;
			}
			set { setXmlDocument("ProxyOutputXSLT", "proxy_output_xslt", value); }
		}

		/// <summary>
		/// Gets the proxy web method.
		/// </summary>
		/// <value>The proxy web method.</value>
		public WebMethod ProxyWebMethod
		{
			get
			{
				WebMethod wm = RepositoryService.GetItem<WebMethod>(this.ProxyWebMethodID);
				if ( wm == null && this.ProxyWebMethodID > 0 ) this.ProxyWebMethodID = -1;
				return wm;
			}
		}

		/// <summary>
		/// Gets or sets the proxy web method ID.
		/// </summary>
		/// <value>The proxy web method ID.</value>
		public int ProxyWebMethodID
		{
			get { return getInt("proxy_webmethod_id", -1); }
			set { setValue("ProxyWebMethodID", "proxy_webmethod_id", value); }
		}

		/// <summary>
		/// Gets the proxy web service.
		/// </summary>
		/// <value>The proxy web service.</value>
		public WebService ProxyWebService
		{
			get
			{
				if ( this.ProxyWebMethod != null ) {
					return this.ProxyWebMethod.WebService;
				} else {
					return null;
				}
			}
		}

		/// <summary>
		/// Gets or sets the receive message queue.
		/// </summary>
		/// <value>The receive message queue.</value>
		public MessageQueueEx ReceiveMessageQueue
		{
			get { return RepositoryService.GetItem<MessageQueueEx>(ReceiveMessageQueueID); }
			set { ReceiveMessageQueueID = value == null ? -1 : value.ID; }
		}

		/// <summary>
		/// Gets or sets the receive message queue ID.
		/// </summary>
		/// <value>The receive message queue ID.</value>
		public int ReceiveMessageQueueID
		{
			get { return ExtendedProperties.ReceiveMessageQueueID; }
			set { ExtendedProperties.ReceiveMessageQueueID = value; }
		}

		public override ItemType RepositoryItemType
		{
			get { return ItemType.LogicalWebMethod; }
		}

		/// <summary>
		/// Gets the repository item type description.
		/// </summary>
		/// <value>The repository item type description.</value>
		public override string RepositoryItemTypeDescription
		{
			get { return ""; }
		}

		/// <summary>
		/// Gets the name of the repository item type.
		/// </summary>
		/// <value>The name of the repository item type.</value>
		public override string RepositoryItemTypeName
		{
			get { return Resources.sLogicalWebMethod; }
		}

		/// <summary>
		/// Gets the selected image.
		/// </summary>
		/// <value>The selected image.</value>
		public override System.Drawing.Image SelectedImage
		{
			get { return this.Image; }
		}

		/// <summary>
		/// Gets the selected image key.
		/// </summary>
		/// <value>The selected image key.</value>
		public override string SelectedImageKey
		{
			get { return this.ImageKey; }
		}

		/// <summary>
		/// Gets or sets the send message queue.
		/// </summary>
		/// <value>The send message queue.</value>
		public MessageQueueEx SendMessageQueue
		{
			get { return RepositoryService.GetItem<MessageQueueEx>(SendMessageQueueID); }
			set { SendMessageQueueID = value == null ? -1 : value.ID; }
		}

		/// <summary>
		/// Gets or sets the send message queue ID.
		/// </summary>
		/// <value>The send message queue ID.</value>
		public int SendMessageQueueID
		{
			get { return ExtendedProperties.SendMessageQueueID; }
			set { ExtendedProperties.SendMessageQueueID = value; }
		}

		/// <summary>
		/// Gets the name of the table.
		/// </summary>
		/// <value>The name of the table.</value>
		public override string TableName
		{
			get { return "logical_webmethods"; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether [use input code mapping].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [use input code mapping]; otherwise, <c>false</c>.
		/// </value>
		public bool UseInputCodeMapping
		{
			get { return ExtendedProperties.UseInputCodeMapping; }
			set { ExtendedProperties.UseInputCodeMapping = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether [use output code mapping].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [use output code mapping]; otherwise, <c>false</c>.
		/// </value>
		public bool UseOutputCodeMapping
		{
			get { return ExtendedProperties.UseOutputCodeMapping; }
			set { ExtendedProperties.UseOutputCodeMapping = value; }
		}

		/// <summary>
		/// Gets or sets the web method.
		/// </summary>
		/// <value>The web method.</value>
		public WebMethod WebMethod
		{
			get { return RepositoryService.GetItem<WebMethod>(WebMethodID); }
			set
			{
				if ( value == null ) WebMethodID = -1;
				else WebMethodID = value.ID;
			}
		}

		/// <summary>
		/// Gets or sets the web method ID.
		/// </summary>
		/// <value>The web method ID.</value>
		public int WebMethodID
		{
			get { return getInt("webmethod_id", -1); }
			set { setValue("WebMethodID", "webmethod_id", value); }
		}

		/// <summary>
		/// Gets or sets the web service.
		/// </summary>
		/// <value>The web service.</value>
		public WebService WebService
		{
			get { return RepositoryService.GetItem<WebService>(WebServiceID); }
			set
			{
				if ( value == null ) WebServiceID = -1;
				else WebServiceID = value.ID;
			}
		}

		/// <summary>
		/// Gets or sets the web service ID.
		/// </summary>
		/// <value>The web service ID.</value>
		public int WebServiceID
		{
			get { return getInt("websvc_id", -1); }
			set { setValue("WebServiceID", "websvc_id", value); }
		}

		#endregion Properties

		#region Methods

		/// <summary>
		/// Copies this instance.
		/// </summary>
		/// <param name="deep"><c>true</c> to recursively copy the item and all subitems;
		/// <c>false</c> to copy only the item itself.</param>
		/// <returns>The copied item.</returns>
		public override IRepositoryItem Copy(bool deep)
		{
			LogicalWebMethod copy = new LogicalWebMethod(this, true);
			this.CopyDataRowToTarget(copy);
			return copy;
		}

		/// <summary>
		/// Gets the assigned human activity.
		/// </summary>
		/// <returns></returns>
		public HumanActivity GetAssignedHumanActivity()
		{
			if ( this.HumanActivityID > 0 ) {
				return this.RepositoryService.GetItem<HumanActivity>(this.HumanActivityID);
			} else {
				return null;
			}
		}

		/// <summary>
		/// Gets the assigned proxy web method.
		/// </summary>
		/// <returns></returns>
		public WebMethod GetAssignedProxyWebMethod()
		{
			if ( this.ProxyWebMethodID > 0 ) {
				return this.RepositoryService.GetItem<WebMethod>(this.ProxyWebMethodID);
			} else {
				return null;
			}
		}

		//	proxy
		/// <summary>
		/// Gets the assigned proxy web service.
		/// </summary>
		/// <returns></returns>
		public WebService GetAssignedProxyWebService()
		{
			WebMethod wm = GetAssignedProxyWebMethod();
			if ( wm != null ) {
				return wm.WebService;
			} else {
				return null;
			}
		}

		/// <summary>
		/// Gets the assigned receive message queue.
		/// </summary>
		/// <returns></returns>
		public MessageQueueEx GetAssignedReceiveMessageQueue()
		{
			if ( this.ReceiveMessageQueueID > 0 ) {
				return this.ReceiveMessageQueue;
			} else {
				return null;
			}
		}

		/// <summary>
		/// Gets the assigned send message queue.
		/// </summary>
		/// <returns></returns>
		public MessageQueueEx GetAssignedSendMessageQueue()
		{
			if ( this.SendMessageQueueID > 0 ) {
				return this.SendMessageQueue;
			} else {
				return null;
			}
		}

		/// <summary>
		/// Gets the assigned web method.
		/// </summary>
		/// <returns></returns>
		public WebMethod GetAssignedWebMethod()
		{
			if ( this.WebMethodID > 0 ) {
				return this.RepositoryService.GetItem<WebMethod>(this.WebMethodID);
			} else {
				return null;
			}
		}

		// new
		/// <summary>
		/// Gets the assigned web service.
		/// </summary>
		/// <returns></returns>
		public WebService GetAssignedWebService()
		{
			if ( this.WebServiceID > 0 ) {
				return this.RepositoryService.GetItem<WebService>(this.WebServiceID);
			} else {
				return null;
			}
		}

		/// <summary>
		/// Gets the callback web method.
		/// </summary>
		/// <returns></returns>
		public WebMethod GetCallbackWebMethod()
		{
			if ( this.CallbackWebMethodID > 0 ) {
				return this.RepositoryService.GetItem<WebMethod>(this.CallbackWebMethodID);
			} else {
				return null;
			}
		}

		/// <summary>
		/// Gets the endpoint rule.
		/// </summary>
		/// <returns></returns>
		public RepositoryBusinessRule GetEndpointRule()
		{
			if ( this.EndpointRuleID > 0 ) {
				return this.RepositoryService.GetItem<RepositoryBusinessRule>(this.EndpointRuleID);
			} else {
				return null;
			}
		}

		/// <summary>
		/// Gets the icon.
		/// </summary>
		/// <returns></returns>
		public override System.Drawing.Icon GetIcon()
		{
			return Icon.FromHandle(Resources.png_logical_method.GetHicon());
		}

		/// <summary>
		/// Gets the logical rule result endpoints.
		/// </summary>
		/// <returns></returns>
		public BindingListEx<LogicalRuleResultEndpoint> GetLogicalRuleResultEndpoints()
		{
			return Global.Data.GetLogicalRuleResultEndpoints(this.ID);
		}

		/// <summary>
		/// Gets the proxy callback web method.
		/// </summary>
		/// <returns></returns>
		public WebMethod GetProxyCallbackWebMethod()
		{
			if ( this.ProxyCallbackWebMethodID > 0 ) {
				return this.RepositoryService.GetItem<WebMethod>(this.ProxyCallbackWebMethodID);
			} else {
				return null;
			}
		}

		/// <summary>
		/// Saves this instance.
		/// </summary>
		/// <returns></returns>
		public override bool Save()
		{
			if ( _properties != null )
				setXmlSerializedObject("ExtendedProperties", "diagram", _properties);

			return base.Save();
		}

		/// <summary>
		/// Sets the assigned proxy web method.
		/// </summary>
		/// <param name="proxywebmethod">The proxywebmethod.</param>
		/// <returns></returns>
		public bool SetAssignedProxyWebMethod(WebMethod proxywebmethod)
		{
			if ( proxywebmethod.ID != this.ProxyWebMethodID ) {
				if ( this.InputXSLT != null || this.OutputXSLT != null ) {
					DialogResult result = MessageBox.Show("Changing the Web Method will delete the mapping of this Logical Method. Are you sure you want to continue?",
						"Change Web Method", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
					if ( result == DialogResult.No ) return false;
				}
				this.InputXSLT = null;
				this.OutputXSLT = null;
				this.InputConnections = null;
				this.OutputConnections = null;
				this.Save();
			}
			if ( proxywebmethod == null ) {
				this.ProxyWebMethodID = -1;
			} else {
				this.ProxyWebMethodID = proxywebmethod.ID;
			}
			return true;
		}

		/// <summary>
		/// Sets the assigned web method.
		/// </summary>
		/// <param name="webmethod">The webmethod.</param>
		/// <returns></returns>
		public bool SetAssignedWebMethod(WebMethod webmethod)
		{
			if ( webmethod == null ) {
				this.WebMethodID = -1;
				this.InputXSLT = null;
				this.OutputXSLT = null;
				this.InputConnections = null;
				this.OutputConnections = null;
			} else {
				if ( webmethod.ID != this.WebMethodID ) {
					if ( this.InputXSLT != null || this.OutputXSLT != null ) {
						DialogResult result = MessageBox.Show("Changing the Web Method will delete the mapping of this Logical Method. Are you sure you want to continue?",
							"Change Web Method", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
						if ( result == DialogResult.No ) return false;
					}
					this.InputXSLT = null;
					this.OutputXSLT = null;
					this.InputConnections = null;
					this.OutputConnections = null;
					this.Save();
				}
				this.WebMethodID = webmethod.ID;
			}
			return true;
		}

		/// <summary>
		/// Sets the callback web method.
		/// </summary>
		/// <param name="callbackwebmethod">The callbackwebmethod.</param>
		public void SetCallbackWebMethod(WebMethod callbackwebmethod)
		{
			if ( callbackwebmethod == null ) {
				this.CallbackWebMethodID = -1;
			} else {
				this.CallbackWebMethodID = callbackwebmethod.ID;
			}
		}

		/// <summary>
		/// Sets the endpoint rule.
		/// </summary>
		/// <param name="endpointrule">The endpointrule.</param>
		public void SetEndpointRule(RepositoryBusinessRule endpointrule)
		{
			if ( endpointrule == null ) {
				this.EndpointRuleID = -1;
			} else {
				this.EndpointRuleID = endpointrule.ID;
			}
		}

		/// <summary>
		/// Sets the logical rule result endpoint.
		/// </summary>
		/// <param name="items">The items.</param>
		public void SetLogicalRuleResultEndpoint(List<LogicalRuleResultEndpoint> items)
		{
			Global.Data.SetLogicalRuleResultEndpoints(this.ID, items);
		}

		/// <summary>
		/// Sets the proxy callback web method.
		/// </summary>
		/// <param name="proxycallbackwebmethod">The proxycallbackwebmethod.</param>
		public void SetProxyCallbackWebMethod(WebMethod proxycallbackwebmethod)
		{
			if ( proxycallbackwebmethod == null ) {
				this.ProxyCallbackWebMethodID = -1;
			} else {
				this.ProxyCallbackWebMethodID = proxycallbackwebmethod.ID;
			}
		}

		// override
		/// <summary>
		/// Shows the new item form.
		/// </summary>
		/// <param name="idRepository">The repository ID.</param>
		/// <param name="bAllowContinue">if set to <c>true</c> to allow save and continue.</param>
		/// <param name="parentItem">The parent item.</param>
		/// <param name="idDomain">The domain ID.</param>
		/// <param name="parentItemNew">The new parent item.</param>
		/// <returns></returns>
		public override System.Windows.Forms.DialogResult ShowNewItemForm(int idRepository,
			bool bAllowContinue, IRepositoryItem parentItem, ref int idDomain, out IRepositoryItem parentItemNew)
		{
			FormCreateNewLogWMeth dlg = new FormCreateNewLogWMeth(this, bAllowContinue);
			dlg.DomainID = idDomain;
			dlg.ShowAllFolders = false;
			dlg.ParentItem = parentItem;
			DialogResult result = dlg.ShowDialog();
			if ( result == DialogResult.OK || result == DialogResult.Retry ) {
				idDomain = dlg.DomainID;
				parentItemNew = dlg.NewParentItem;
			} else {
				idDomain = 0;
				parentItemNew = null;
			}
			return result;
		}

		/// <summary>
		/// Shows the new item form ex.
		/// </summary>
		/// <param name="idRepository">The id repository.</param>
		/// <param name="bAllowContinue">if set to <c>true</c> [b allow continue].</param>
		/// <param name="parentItem">The parent item.</param>
		/// <param name="idDomain">The id domain.</param>
		/// <param name="parentItemNew">The parent item new.</param>
		/// <param name="bobjInput">The bobj input.</param>
		/// <param name="bobjOutput">The bobj output.</param>
		/// <returns></returns>
		public System.Windows.Forms.DialogResult ShowNewItemFormEx(int idRepository,
			bool bAllowContinue, IRepositoryItem parentItem, ref int idDomain, out IRepositoryItem parentItemNew,
			BusinessObject bobjInput, BusinessObject bobjOutput)
		{
			FormCreateNewLogWMeth dlg = new FormCreateNewLogWMeth(this, bAllowContinue);
			dlg.DomainID = idDomain;
			dlg.ShowAllFolders = false;
			dlg.ParentItem = parentItem;
			dlg.InputBusinessObject = bobjInput;
			dlg.OutputBusinessObject = bobjOutput;
			DialogResult result = dlg.ShowDialog();
			if ( result == DialogResult.OK || result == DialogResult.Retry ) {
				idDomain = dlg.DomainID;
				parentItemNew = dlg.NewParentItem;
			} else {
				idDomain = 0;
				parentItemNew = null;
			}
			return result;
		}

		#endregion Methods

		#endregion Public Members

		#region Internal Members

		#region Methods

		/// <summary>
		/// Sets the input business object ID.
		/// </summary>
		/// <param name="value">The value.</param>
		internal void SetInputBusinessObjectID(int value)
		{
			if ( this.InputBusinessObjectID == value ) return; // EXIT
			BindingListEx<Verb> lst = Global.Data.GetVerbsOfLogicalMethod(this.ID);
			setValue("InputBusinessObjectID", "input_bobj_id", value);
			if ( lst.Count > 0 ) {
				foreach ( var item in lst ) {
					item.SetInputBusinessObjectID(value);
					item.Save();
				}
			}
		}

		/// <summary>
		/// Sets the output business object ID.
		/// </summary>
		/// <param name="value">The value.</param>
		internal void SetOutputBusinessObjectID(int value)
		{
			if ( this.OutputBusinessObjectID == value ) return; // EXIT
			BindingListEx<Verb> lst = Global.Data.GetVerbsOfLogicalMethod(this.ID);
			setValue("OutputBusinessObjectID", "output_bobj_id", value);
			if ( lst.Count > 0 ) {
				foreach ( var item in lst ) {
					item.SetOutputBusinessObjectID(value);
					item.Save();
				}
			}
		}

		#endregion Methods

		#endregion Internal Members

		#region Private Members

		#region Fields

		// proxy properties
		private LogicalMethodProperties _properties = null;

		#endregion Fields

		#endregion Private Members
	}

	#region Enumerations

	public enum LogicalMethodAssignedTo
	{
		WebServiceMethod = 0,
		HumanActivity = 1,
		EndpointRule = 2,
		MessageQueue = 3,
	}

	#endregion Enumerations

	public class LogicalMethodProperties
	{
		#region Public Members

		#region Properties

		/// <summary>
		/// Gets or sets the input code mapping.
		/// </summary>
		/// <value>The input code mapping.</value>
		public string InputCodeMapping
		{
			get { return UseInputCodeMapping ? _inputCodeMapping : null; }
			set { _inputCodeMapping = value; }
		}

		/// <summary>
		/// Gets or sets the output code mapping.
		/// </summary>
		/// <value>The output code mapping.</value>
		public string OutputCodeMapping
		{
			get { return UseOutputCodeMapping ? _outputCodeMapping : null; }
			set { _outputCodeMapping = value; }
		}

		/// <summary>
		/// Gets or sets the receive message queue ID.
		/// </summary>
		/// <value>The receive message queue ID.</value>
		public int ReceiveMessageQueueID
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the send message queue ID.
		/// </summary>
		/// <value>The send message queue ID.</value>
		public int SendMessageQueueID
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets a value indicating whether [use input code mapping].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [use input code mapping]; otherwise, <c>false</c>.
		/// </value>
		[DefaultValue(false)]
		public bool UseInputCodeMapping
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets a value indicating whether [use output code mapping].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [use output code mapping]; otherwise, <c>false</c>.
		/// </value>
		public bool UseOutputCodeMapping
		{
			get;
			set;
		}

		#endregion Properties

		#endregion Public Members

		#region Private Members

		#region Fields

		private string _inputCodeMapping = null;
		private string _outputCodeMapping = null;

		#endregion Fields

		#endregion Private Members

		#region Other

		/// <summary>
		/// Gets or sets a value indicating whether the message queue sends or receive data.
		/// </summary>
		/// <value><c>true</c> if message queue sends; otherwise (receive), <c>false</c>.</value>
		//public bool MessageQueueSend { get; set; }

		#endregion Other
	}

	public class LogicalRuleResultEndpoint : ISupportLogicalPhysicalMapping
	{
		#region Initialization

		/// <summary>
		/// Initializes a new instance of the <see cref="LogicalRuleResultEndpoint"/> class.
		/// </summary>
		/// <param name="serviceProvider">The service provider.</param>
		/// <param name="logMethodID">The log method ID.</param>
		public LogicalRuleResultEndpoint(IServiceProvider serviceProvider, int logMethodID)
		{
			_serviceProvider = serviceProvider;
			_repService = (RepositoryService)_serviceProvider.GetService(typeof(RepositoryService));

			this.LogicalMethodID = logMethodID;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="LogicalRuleResultEndpoint"/> class.
		/// </summary>
		/// <param name="serviceProvider">The service provider.</param>
		/// <param name="logMethodID">The log method ID.</param>
		/// <param name="ruleresult">The ruleresult.</param>
		public LogicalRuleResultEndpoint(IServiceProvider serviceProvider, int logMethodID, string ruleresult)
		{
			_serviceProvider = serviceProvider;
			_repService = (RepositoryService)_serviceProvider.GetService(typeof(RepositoryService));

			this.LogicalMethodID = logMethodID;
			this.EndpointRuleResult = ruleresult;
		}

		#endregion Initialization

		#region Public Members

		#region Properties

		/// <summary>
		/// Gets the callback web method.
		/// </summary>
		/// <value>The callback web method.</value>
		public WebMethod CallbackWebMethod
		{
			get
			{
				WebMethod wm = _repService.GetItem<WebMethod>(this.CallbackWebMethodID);
				if ( wm == null && this.CallbackWebMethodID > 0 ) this.CallbackWebMethodID = -1;
				return wm;
			}
		}

		/// <summary>
		/// Gets or sets the callback web method ID.
		/// </summary>
		/// <value>The callback web method ID.</value>
		public int CallbackWebMethodID
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the endpoint rule result.
		/// </summary>
		/// <value>The endpoint rule result.</value>
		public string EndpointRuleResult
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the human activity.
		/// </summary>
		/// <value>The human activity.</value>
		public HumanActivity HumanActivity
		{
			get
			{
				HumanActivity ha = _repService.GetItem<HumanActivity>(this.HumanActivityID);
				if ( ha == null && this.HumanActivityID > 0 ) this.HumanActivityID = -1;
				return ha;
			}
		}

		/// <summary>
		/// Gets or sets the human activity ID.
		/// </summary>
		/// <value>The human activity ID.</value>
		public int HumanActivityID
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the input business object.
		/// </summary>
		/// <value>The input business object.</value>
		public BusinessObject InputBusinessObject
		{
			get { return this.LogicalMethod.InputBusinessObject; }
			set { this.LogicalMethod.InputBusinessObject = value; }
		}

		/// <summary>
		/// Gets or sets the input business object ID.
		/// </summary>
		/// <value>The input business object ID.</value>
		public int InputBusinessObjectID
		{
			get { return this.LogicalMethod.InputBusinessObjectID; }
			set { this.LogicalMethod.InputBusinessObjectID = value; }
		}

		/// <summary>
		/// Gets or sets the input code mapping.
		/// </summary>
		/// <value>The input code mapping.</value>
		public string InputCodeMapping
		{
			get { return UseInputCodeMapping ? _inputCodeMapping : null; }
			set { _inputCodeMapping = value; }
		}

		/// <summary>
		/// Gets or sets the input connections.
		/// </summary>
		/// <value>The input connections.</value>
		public string InputConnections
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the input XSLT.
		/// </summary>
		/// <value>The input XSLT.</value>
		public XsltDocument InputXSLT
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the logical method.
		/// </summary>
		/// <value>The logical method.</value>
		public LogicalWebMethod LogicalMethod
		{
			get
			{
				return _repService.GetItem<LogicalWebMethod>(this.LogicalMethodID);
			}
		}

		// base properties (stored in database)
		/// <summary>
		/// Gets or sets the logical method ID.
		/// </summary>
		/// <value>The logical method ID.</value>
		public int LogicalMethodID
		{
			get;
			protected set;
		}

		/// <summary>
		/// Gets or sets the name.
		/// </summary>
		/// <value>The name.</value>
		public string Name
		{
			get { return LogicalMethod.Name; }
			set { /* do nothing*/ }
		}

		/// <summary>
		/// Gets or sets the output business object.
		/// </summary>
		/// <value>The output business object.</value>
		public BusinessObject OutputBusinessObject
		{
			get { return this.LogicalMethod.OutputBusinessObject; }
			set { this.LogicalMethod.OutputBusinessObject = value; }
		}

		/// <summary>
		/// Gets or sets the output business object ID.
		/// </summary>
		/// <value>The output business object ID.</value>
		public int OutputBusinessObjectID
		{
			get { return this.LogicalMethod.OutputBusinessObjectID; }
			set { this.LogicalMethod.OutputBusinessObjectID = value; }
		}

		/// <summary>
		/// Gets or sets the output code mapping.
		/// </summary>
		/// <value>The output code mapping.</value>
		public string OutputCodeMapping
		{
			get { return UseOutputCodeMapping ? _outputCodeMapping : null; }
			set { _outputCodeMapping = value; }
		}

		/// <summary>
		/// Gets or sets the output connections.
		/// </summary>
		/// <value>The output connections.</value>
		public string OutputConnections
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the output XSLT.
		/// </summary>
		/// <value>The output XSLT.</value>
		public XsltDocument OutputXSLT
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the proxy callback web method.
		/// </summary>
		/// <value>The proxy callback web method.</value>
		public WebMethod ProxyCallbackWebMethod
		{
			get
			{
				WebMethod wm = _repService.GetItem<WebMethod>(this.ProxyCallbackWebMethodID);
				if ( wm == null && this.ProxyCallbackWebMethodID > 0 ) this.ProxyCallbackWebMethodID = -1;
				return wm;
			}
		}

		/// <summary>
		/// Gets or sets the proxy callback web method ID.
		/// </summary>
		/// <value>The proxy callback web method ID.</value>
		public int ProxyCallbackWebMethodID
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the proxy input connections.
		/// </summary>
		/// <value>The proxy input connections.</value>
		public string ProxyInputConnections
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the proxy input XSLT.
		/// </summary>
		/// <value>The proxy input XSLT.</value>
		public XsltDocument ProxyInputXSLT
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the proxy output connections.
		/// </summary>
		/// <value>The proxy output connections.</value>
		public string ProxyOutputConnections
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the proxy output XSLT.
		/// </summary>
		/// <value>The proxy output XSLT.</value>
		public XsltDocument ProxyOutputXSLT
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the proxy web method.
		/// </summary>
		/// <value>The proxy web method.</value>
		public WebMethod ProxyWebMethod
		{
			get
			{
				WebMethod wm = _repService.GetItem<WebMethod>(this.ProxyWebMethodID);
				if ( wm == null && this.ProxyWebMethodID > 0 ) this.ProxyWebMethodID = -1;
				return wm;
			}
		}

		// proxy properties
		/// <summary>
		/// Gets or sets the proxy web method ID.
		/// </summary>
		/// <value>The proxy web method ID.</value>
		public int ProxyWebMethodID
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the proxy web service.
		/// </summary>
		/// <value>The proxy web service.</value>
		public WebService ProxyWebService
		{
			get
			{
				if ( this.ProxyWebMethod != null ) {
					return this.ProxyWebMethod.WebService;
				} else {
					return null;
				}
			}
		}

		/// <summary>
		/// Gets the receive message queue.
		/// </summary>
		/// <value>The receive message queue.</value>
		public MessageQueueEx ReceiveMessageQueue
		{
			get
			{
				MessageQueueEx msmq = _repService.GetItem<MessageQueueEx>(this.ReceiveMessageQueueID);
				if ( msmq == null && this.ReceiveMessageQueueID > 0 ) this.ReceiveMessageQueueID = -1;
				return msmq;
			}
		}

		/// <summary>
		/// Gets or sets the receive message queue ID.
		/// </summary>
		/// <value>The receive message queue ID.</value>
		public int ReceiveMessageQueueID
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the send message queue.
		/// </summary>
		/// <value>The send message queue.</value>
		public MessageQueueEx SendMessageQueue
		{
			get
			{
				MessageQueueEx msmq = _repService.GetItem<MessageQueueEx>(this.SendMessageQueueID);
				if ( msmq == null && this.SendMessageQueueID > 0 ) this.SendMessageQueueID = -1;
				return msmq;
			}
		}

		/// <summary>
		/// Gets or sets the send message queue ID.
		/// </summary>
		/// <value>The send message queue ID.</value>
		public int SendMessageQueueID
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets a value indicating whether [use input code mapping].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [use input code mapping]; otherwise, <c>false</c>.
		/// </value>
		public bool UseInputCodeMapping
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets a value indicating whether [use output code mapping].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [use output code mapping]; otherwise, <c>false</c>.
		/// </value>
		public bool UseOutputCodeMapping
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the web method.
		/// </summary>
		/// <value>The web method.</value>
		public WebMethod WebMethod
		{
			get
			{
				WebMethod wm = _repService.GetItem<WebMethod>(this.WebMethodID);
				if ( wm == null && this.WebMethodID > 0 ) this.WebMethodID = -1;
				return wm;
			}
		}

		/// <summary>
		/// Gets or sets the web method ID.
		/// </summary>
		/// <value>The web method ID.</value>
		public int WebMethodID
		{
			get;
			set;
		}

		// additional properties
		/// <summary>
		/// Gets the web service.
		/// </summary>
		/// <value>The web service.</value>
		public WebService WebService
		{
			get
			{
				if ( this.WebMethod != null ) {
					return this.WebMethod.WebService;
				} else {
					return null;
				}
			}
		}

		#endregion Properties

		#endregion Public Members

		#region Private Members

		#region Fields

		private string _inputCodeMapping = null;
		private string _outputCodeMapping = null;
		private RepositoryService _repService;
		private IServiceProvider _serviceProvider;

		#endregion Fields

		#endregion Private Members
	}

}